package com.ailargemodel.service.impl;


import com.ailargemodel.common.BaseResponse;
import com.ailargemodel.common.ErrorCode;
import com.ailargemodel.common.RedisLimiterManager;
import com.ailargemodel.common.UserThreadLocal;
import com.ailargemodel.common.exception.BusinessException;
import com.ailargemodel.common.utils.ResultUtil;
import com.ailargemodel.mapper.QuesttionMapper;
import com.ailargemodel.mapper.UserMapper;
import com.ailargemodel.pojo.DTO.HistoryDTO;
import com.ailargemodel.pojo.Questtion;
import com.ailargemodel.pojo.RedisConstants;
import com.ailargemodel.pojo.User;
import com.ailargemodel.service.AIService;
import com.ailargemodel.service.UserService;
import com.ailargemodel.utils.AIUtils;
import com.alibaba.dashscope.aigc.generation.Generation;
import com.alibaba.dashscope.aigc.generation.GenerationResult;
import com.alibaba.dashscope.aigc.generation.models.QwenParam;
import com.alibaba.dashscope.common.History;
import com.alibaba.dashscope.common.Message;
import com.alibaba.dashscope.common.Role;
import com.alibaba.dashscope.exception.ApiException;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.ollama.OllamaChatModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;


import java.time.Instant;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Service
@Slf4j
public class AIServiceimpl implements AIService {
    @Autowired
    private QuesttionMapper questtionMapper;

    @Autowired
    private AIUtils aiUtils;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private OllamaChatModel ollamaChatModel;


    @Override
    public BaseResponse Inquire(String context, User user,Integer grade)
            throws NoApiKeyException, ApiException, InputRequiredException {
     /*       Generation gen = new Generation();
            Message userMsg = Message.builder().role(Role.USER.getValue()).content(context).build();
            QwenParam param =
                    QwenParam.builder().model("qwen2-72b-instruct").messages(Arrays.asList(userMsg))
                            .resultFormat(QwenParam.ResultFormat.MESSAGE)
                            .topP(0.8)
                            .build();
            GenerationResult result = gen.call(param);*/
            String msg= ollamaChatModel.call(context);
          /*  System.out.println(result);
            String msg = result.getOutput().getChoices().get(0).getMessage().getContent();
*/
        saveDB(6,context,msg,user,grade);

        return ResultUtil.sucess(msg);
    }

    @Override
    public BaseResponse translate(User user, String topic, Integer grade) throws NoApiKeyException, InputRequiredException {
        String message = "请以下内容翻译为中文:" +topic;
        String msg = aiUtils.callWithMessage(message);
        log.info(msg);

        saveDB(1,message,msg,user,grade);

        return ResultUtil.sucess(msg);
    }

    @Override
    public BaseResponse unscramble(User user, String topic, Integer grade) throws NoApiKeyException, InputRequiredException {
//        TODO 后续 应该要对指令 做一些 优化
//        TODO 要对 题目 翻译到什么 语言呢?(只做中文, 英文的翻译吗)
        String message = "请使用中文给下述题目做一个题目的解读:" +topic;
        String msg = aiUtils.callWithMessage(message);
        log.info(msg);

        saveDB(2,message,msg,user,grade);

        return ResultUtil.sucess(msg);
    }

    @Override
    public BaseResponse guidance(User user, String topic, Integer grade) throws NoApiKeyException, InputRequiredException {
//        TODO 后续 应该要对指令 做一些 优化
//        TODO 要对 题目 翻译到什么 语言呢?(只做中文, 英文的翻译吗)
        String message = "请使用中文为此题,做一些代码思路上的引导:" +topic;
        String msg = aiUtils.callWithMessage(message);
        log.info(msg);

        saveDB(3,message,msg,user,grade);

        return ResultUtil.sucess(msg);    }

    @Override
    public BaseResponse correction(User user, String code, Integer grade) throws NoApiKeyException, InputRequiredException {
//        TODO 后续 应该要对指令 做一些 优化
//        TODO 要对 题目 翻译到什么 语言呢?(只做中文, 英文的翻译吗)
        String message = "请为使用中文下述代码进行纠错:" +code;
        String msg = aiUtils.callWithMessage(message);
        log.info(msg);

        saveDB(4,message,msg,user,grade);

        return ResultUtil.sucess(msg);    }

    @Override
    public BaseResponse evaluation(User user , String code, Integer grade) throws NoApiKeyException, InputRequiredException {
        //        TODO 后续 应该要对指令 做一些 优化
//        TODO 要对 题目 翻译到什么 语言呢?(只做中文, 英文的翻译吗)
        String message = "请使用中文下述代码的质量做一个评估,并打分:" +code;
        String msg = aiUtils.callWithMessage(message);
        log.info(msg);

        saveDB(5,message,msg,user,grade);

        return ResultUtil.sucess(msg);
    }

    /**
     * 查询AI 后 存储 数据库的功能
     * @param functionId
     * @param message
     * @param msg
     * @param user
     * @param grade
     */
    private void saveDB(Integer functionId, String message,String msg, User user,Integer grade) {
        List<Questtion> questtions = questtionMapper.selectQuestionList(user.getStudyId());
        Questtion questtion = new Questtion();
        int lastQuestionNum = 0;

        if(questtions.size() >=1){
//        有则 , 直接取出来信息 , 添加新的questionId+1 , context , msg
            Questtion lastQuesttion = questtions.get(questtions.size() -1);

            lastQuestionNum = lastQuesttion.getQuestionId()+1;

            questtion.setStudyId(user.getStudyId());
            questtion.setQuestionId(lastQuesttion.getQuestionId()+1);
            questtion.setQuestion(message);
            questtion.setAnswer(msg);
            questtion.setQuestionTime(Date.from(Instant.now()));
            questtion.setFuctionNumber(functionId);
            questtion.setGrade(grade == 100?0: grade);
            questtion.setConversationId(user.getConversationId());
        }else {
//        没有,则在question中添加新的 不知道为什么注入不进去
            questtion.setStudyId(user.getStudyId());
            questtion.setQuestionId(0);
            questtion.setQuestion(message);
            questtion.setAnswer(msg);
            questtion.setQuestionTime(Date.from(Instant.now()));
            questtion.setFuctionNumber(functionId);
            questtion.setGrade(grade == 100?0: grade);
            questtion.setConversationId(user.getConversationId());
        }
//        MP 注入不景区
        questtionMapper.add(questtion);
//        更新 user 表中的 Question_number字段
        userMapper.updateQuestionNum(user, lastQuestionNum);
    }


    /**
     * 查询历史记录
     * @param pageSize
     * @param pageNum
     * @param studyId
     * @return
     */
    @Override
    public PageInfo<Questtion> selectHistoryBystudyId(Integer pageSize,Integer pageNum, String studyId) {
//        先判断 这个 studyId 是否存在
        User user = userMapper.selectByUser(new User(studyId));
        if (user == null) {
            throw new BusinessException(ErrorCode.DATABASE_MATCH_EMPTY_ERROR);
        }

//        开始分页
        PageHelper.startPage(pageNum,pageSize);

//        查询历史列表
        List<Questtion> questtionsList = questtionMapper.selectQuestionList(studyId);
//        数据脱敏
        List<Questtion> safeQuestionList = questtionsList.stream().map(question -> {
            Questtion safeQuestion = new Questtion(question.getStudyId(), question.getQuestionId(), question.getQuestion(), question.getAnswer(), question.getFuctionNumber(),question.getQuestionTime(), question.getConversationId(),question.getGrade());
            return safeQuestion;
        }).sorted(new Comparator<Questtion>() {
//            按时间新老 , 进行划分
            @Override
            public int compare(Questtion o1, Questtion o2) {
                int i = o1.getQuestionTime().getTime() > o2.getQuestionTime().getTime() ? -1 : 1;
                return i;
            }
        }).collect(Collectors.toList());


        PageInfo<Questtion> pageInfo = new PageInfo<>(safeQuestionList);


        return pageInfo;
    }

    @Override
    public BaseResponse addNewConversation(User loginUser, String sessionId) {
//        先判断当前的 conversationId 下的问题是否只有零个 ， 若是，则拒绝创建新的会话
        int sum = questtionMapper.selectNumsByLoginUser(loginUser);
        if (sum == 0){
            ResultUtil.error(ErrorCode.CONVERSATION_NUM_LITTLE);
        }
//        修改session， 和修改Redis的数据
        User updateUser = new User();
        BeanUtils.copyProperties(loginUser, updateUser);
        updateUser.setConversationId(loginUser.getConversationId() + 1);


        String Key = RedisConstants.LOGIN_CODE_KEY + sessionId;
        Gson gson = new Gson();
        Map<String, String> userMap = new HashMap<>();
        userMap.put(sessionId, gson.toJson(updateUser));
        stringRedisTemplate.delete(Key);
        stringRedisTemplate.opsForHash().putAll(Key,userMap);
        stringRedisTemplate.expire(Key, RedisConstants.LOGIN_USER_TTL, TimeUnit.MINUTES);

        return ResultUtil.sucess();
    }


}
